package top.joylee.example.grpc;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.joylee.example.grpc.hello.GreeterGrpc;
import top.joylee.example.grpc.hello.HelloRequest;
import top.joylee.example.grpc.hello.HelloResponse;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Hello gRPC 服务端
 * 读取客户端发过来的name，加上Hello响应和客户端
 */
public class HelloServer {
    private final static Logger log = LoggerFactory.getLogger(HelloServer.class);

    private Server server;

    public static void main(String[] args) throws Exception {
        HelloServer helloServer = new HelloServer();
        helloServer.start();
        helloServer.blockUntilShutdown();
    }

    private void start() throws IOException {
        int port = 50001;
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        log.info("Server started.listening on {}", port);

        // 监听jvm shutdown 事件，并处理
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.error("**** shutdown g=RPC server since JVM is shutting down");
            try {
                stop();
            } catch (InterruptedException e) {
                log.error("await stop error,interrupted", e);
            }
            log.info("**** server shut down ,good bye ***");
        }));
    }

    private void blockUntilShutdown() throws InterruptedException {
        if (Objects.isNull(server)) {
            return;
        }
        server.awaitTermination();
    }


    private void stop() throws InterruptedException {
        if (Objects.isNull(server)) {
            return;
        }
        server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
    }


    private static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
            log.info("...receive {} request", request.getName());
            HelloResponse response = HelloResponse.newBuilder().setMessage("Hello \t" + request.getName()).build();
            responseObserver.onNext(response);
            responseObserver.onCompleted();
            log.info("reply {} complete...", request.getName());
        }
    }
}
